# Account security and TOTP MFA

> The managed `/account/security` page shows the user's Auth providers and supplies real email, password, and authenticator-app controls. Email and password mutations reauthenticate password users at the server boundary. OAuth-only users see those controls disabled because they do not have a password identity to reauthenticate.

# Account security and TOTP MFA

The managed `/account/security` page shows the user's Auth providers and supplies real email, password, and authenticator-app controls. Email and password mutations reauthenticate password users at the server boundary. OAuth-only users see those controls disabled because they do not have a password identity to reauthenticate.

## Configure authenticator MFA

```ts
AUTHENTICATION: {
  MFA_TOTP: {
    REQUIRED_FOR_SIGN_IN: true,
  },
},
```

Enrolment and factor management are always displayed. `REQUIRED_FOR_SIGN_IN` sends an enrolled user whose session is at AAL1 through `/account/mfa` before completing a password, OTP, magic-link, or OAuth sign-in destination. If no verified factor exists, the session has no AAL2 step to perform; the user may enrol from Security.

For local development, set both `enroll_enabled = true` and `verify_enabled = true` under `[auth.mfa.totp]` in `supabase/config.toml`, then restart the local Supabase stack. Hosted projects use their separate Auth MFA setting in the Supabase Dashboard; changing the local TOML file does not change a hosted project.

Supacharger uses Supabase Auth's `listFactors`, `enroll`, `challengeAndVerify`, and `unenroll` operations. It never stores a TOTP secret in application tables. An unverified enrolment can be cancelled. A verified factor requires a current six-digit code when the session needs to step up before removal.

## Email and password changes

`POST /api/account/email` parses the request with Zod, verifies the current user and password identity, reauthenticates the current password, and asks Supabase Auth to send the secure email-change confirmation. The redirect returns to `/account/security`.

`POST /api/account/update-password` applies the configured password policy, verifies the current password, and calls `auth.updateUser`. OAuth-only accounts keep both forms visibly unavailable instead of exposing a control that cannot succeed.

## Product presentation

The security route and non-visual behaviour are managed. A developer-owned `src/supacharger.adapters/account/security-page.tsx` starter may preserve an authorised product presentation. The CLI installs this adapter only when missing and never overwrites it. Specdrive uses this seam; its restricted presentation is not copied into the open-source Core.
